home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / ada / gwuada_9.zip / LOAD.C < prev    next >
C/C++ Source or Header  |  1993-07-27  |  15KB  |  472 lines

  1. /*
  2.  * Copyright (C) 1985-1992  New York University
  3.  * 
  4.  * This file is part of the Ada/Ed-C system.  See the Ada/Ed README file for
  5.  * warranty (none) and distribution info and also the GNU General Public
  6.  * License for more details.
  7.  
  8.  */
  9.  
  10. /* load.c - procedures to load to libraries and axq files */
  11.  
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include "config.h"
  16. #include "int.h"
  17. #include "segment.h"
  18. #include "slot.h"
  19. #include "ivars.h"
  20. #include "ifile.h"
  21. #include "miscp.h"
  22. #include "libfp.h"
  23. #include "axqrp.h"
  24. #include "loadp.h"
  25.  
  26. static void init_predef();
  27. static void init_library(IFILE *, char *);
  28. static char *unit_name_name(char *);
  29. static int *unit_list_new();
  30. static void unit_list_copy(int *, int *);
  31. static int unit_list_next(int *);
  32. static int in_loaded(char *);
  33.  
  34. /* Various sets and maps in the SETL version are represented using
  35.  * strings in the C version. This is possible since they all have as
  36.  * their domain unit_numbers, and the total number of unit_numbers is
  37.  * known before these are needed. The initial values of these items
  38.  * are set by 
  39.  *    s = unit_list_new(). 
  40.  * Once defined, s[i] is YES if unit i is in the set, NO otherwise.
  41.  * These sets are kept as a vector of (short) integers, with the
  42.  * first (zeroth) element giving the number of elements, in much the
  43.  * way is tuples are represented in the other parts of the compiler.
  44.  */
  45. #define YES 1
  46. #define NO 0
  47.  
  48. static char  **file_number;
  49. static int  **PRECEDES_MAP;
  50. static char  **unit_names;
  51. static int     unit_count;
  52. static int   interfaced_unit = 0;
  53. static int   obsolete_error = FALSE;
  54.  
  55. /* The following struct is used main a list of the units actually loaded. */
  56. struct axq_loaded {
  57.     struct axq_loaded  *loaded_next;
  58.     char   *loaded_name;
  59. };
  60. static struct axq_loaded  *ll_head; /* pointer to head of list */
  61.  
  62. static void init_predef()                                        /*;init_predef*/
  63. {
  64.     int     i;
  65.     static char *predef_units[] = {
  66.         "spSYSTEM", "spIO_EXCEPTIONS", "spSEQUENTIAL_IO",
  67.         "boSEQUENTIAL_IO", "spDIRECT_IO", "boDIRECT_IO",
  68.         "spTEXT_IO", "boTEXT_IO", "spCALENDAR", "boCALENDAR",
  69.         "ssUNCHECKED_DEALLOCATION", "suUNCHECKED_DEALLOCATION",
  70.         "ssUNCHECKED_CONVERSION", "suUNCHECKED_CONVERSION"
  71.     };
  72.  
  73.     /* Set values for unit_names, file_number and PRECEDES information for
  74.      * predefined compilation units, since they do not appear in any library
  75.      */
  76.     /* allocate unit names - recalling it is ones origin */
  77.     unit_count = 14;
  78.     unit_names = (char **) emalloct((unit_count + 1) * sizeof(char *),
  79.       "unit_names");
  80.     PRECEDES_MAP = (int **) emalloct(sizeof(char **) *(unit_count + 1),
  81.       "precedes_map");
  82.     PRECEDES_MAP[0] =  (int *) unit_count;
  83.     file_number = (char **) emalloct(sizeof(char **) *(unit_count + 1),
  84.       "file_number");
  85.     for (i = 1; i <= unit_count; i++) {
  86.         unit_names[i] = predef_units[i - 1];
  87.         file_number[i] = "0";
  88.         PRECEDES_MAP[i] = unit_list_new();
  89.     }
  90. }
  91.  
  92. void load_lib(char *filename, IFILE *libfile, Axq axq, char *main_unit,
  93.   char **argv)                                                    /*;load_lib*/
  94. {
  95.     /* This procedure looks for the main unit
  96.      * and loads it, together with all units on which it depends directly
  97.      * or indirectly. Dependences are taken from map precedes.
  98.      */
  99.  
  100.     struct axq_loaded  *ll_new;
  101.     int   *main_units, *bound_units, *new_main_units, *to_read, *precedes;
  102.     int       unitn;
  103.     int     i, name, pi;
  104.     int     is_predef_unit;
  105.     int     nmain_units;
  106.     char   *idle_task_name, *unit_file;
  107.     IFILE * axqfile;
  108.     char    exename[100];
  109.     char   *PREDEFNAME;
  110.     char   *file_name, *l_name, *t_name;
  111.  
  112.     ll_head = (struct axq_loaded   *) 0; /* Initially, no files loaded */
  113.     init_library(libfile,main_unit);
  114.     main_units = unit_list_new();
  115.     bound_units = unit_list_new();
  116.     for (i = 1; i <= unit_count; i++) {
  117.         if (streq(unit_name_type(unit_names[i]), "ma"))
  118.             main_units[i] = YES;
  119.     }
  120.     if (main_unit != (char *) 0) {
  121.         /* main_units := {[x,y]: [x,y] in main_units 
  122.          *        | y = '_'+MAINUNIT+'_idle_task'}; 
  123.          */
  124.         idle_task_name = strjoin(main_unit, "_idle_task");
  125.         for (name = 1; name <= unit_count; name++) {
  126.             if (main_units[name] == NO)
  127.                 continue;
  128.             if (streq(idle_task_name, unit_names[name]+2))
  129.                 bound_units[name] = YES;
  130.         }
  131.         unit_list_copy(main_units, bound_units);
  132.     }
  133.     nmain_units = 0;
  134.     for (i = 1; i <= main_units[0]; i++)
  135.         if (main_units[i]) nmain_units++;
  136.     if (nmain_units == 0) {
  137.         printf("*** Unbound library, execution not allowed\n");
  138.         exit(RC_ERRORS);
  139.     }
  140.     else if (nmain_units > 1) {
  141.         printf("*** More than one main program in library\n");
  142.         printf("    Use option: -m(one of the following)\n");
  143.         for (name = 1; name <= unit_count; name++) {
  144.             if (main_units[name] == NO)
  145.                 continue;
  146.             unit_names[name][strlen(unit_names[name])-10] = '\0';
  147.             /* name of the form _xxx_idle_task, print only xxx */
  148.             printf("    %s\n", unit_names[name]+2);
  149.         }
  150.         exit(RC_ERRORS);
  151.     }
  152.     else {
  153. #ifndef INTERFACE
  154. #ifdef SUPPORT_PRAGMA_INTERFACE
  155.         /* at this point, if the main binding unit is interfaced, we run
  156.          * the executable which has been built with the procedure interface
  157.          */
  158.         if (interfaced_unit != 0) {
  159.             sprintf(exename,"%s%s%s.exe",filename,DIR_DELIMITER,
  160.               file_number[interfaced_unit]);
  161.             execvp(exename,argv);
  162.         }
  163. #endif
  164. #endif
  165.         if (obsolete_error) {
  166.             printf(
  167.               "*** Main binding unit obsolete, please recompile or rebind \n");
  168.             exit(RC_ERRORS);
  169.         }
  170.         to_read = unit_list_new();
  171.         while(unit_list_next(main_units)) {
  172.             for (name = 1; name <= unit_count; name++) {
  173.                 if (main_units[name] == NO)
  174.                     continue;
  175.                 to_read[name] = YES;
  176.             }
  177.             /* main_units := {} +/{ precedes{u} : u in main_units}; */
  178.             new_main_units = unit_list_new();
  179.             /* for name in main_units */
  180.             for (name = 1; name <= unit_count; name++) {
  181.                 if (main_units[name] == NO)
  182.                     continue;
  183.                 precedes = PRECEDES_MAP[name];
  184.                 for (pi = 1; pi <= unit_count; pi++) {
  185.                     if (precedes[pi] == NO)
  186.                         continue;
  187.                     new_main_units[pi] = YES;
  188.                 }
  189.             }
  190.             unit_list_copy(main_units, new_main_units);
  191.         }
  192.         while((unitn = unit_list_next(to_read))) {
  193.             to_read[unitn]  = NO;        /* remove from set */
  194.             if (unitn == 0) {
  195.                 /* junk unit number - binder shouldn't be putting this out */
  196.                 printf("load.c: skipping 0 case\n");
  197.                 continue;
  198.             }
  199.             if (unitn <= unit_count    /* false if "ghost package body" */
  200.             &&(!in_loaded(file_number[unitn]))) {
  201.                 unit_file = (char *) file_number[unitn];
  202.                 file_name = unit_file;
  203.                 is_predef_unit =  streq(unit_file,"0");
  204.                 if (is_predef_unit) {
  205.                     PREDEFNAME = predef_env();
  206.                     l_name = libset(PREDEFNAME); /* use predef library */
  207.                     file_name = "predef";
  208.                 }
  209.                 axqfile = ifopen(file_name, "axq", "r", 0);
  210.                 read_axq(axqfile, axq);
  211.                 ifclose(axqfile);
  212.                 if (is_predef_unit)
  213.                     t_name = libset(l_name); /* restore user library */
  214.                 if (!in_loaded(unit_file))
  215.                     ll_new = (struct axq_loaded *)
  216.                       smalloc(sizeof(struct axq_loaded));
  217.                 ll_new->loaded_next = ll_head;
  218.                 ll_new->loaded_name = unit_file;
  219.                 ll_head = ll_new;
  220.             }
  221.         }            /* while */
  222.     }
  223. }
  224.  
  225. static void init_library(IFILE *ifile, char *main_unit)        /*;init_library*/
  226. {
  227.     /*
  228.      * retrieve information from ifile
  229.      */
  230.  
  231.     int     i, j, n, m, unumber,cur_level;
  232.     int        ignore;
  233.     int     punit;
  234.     char   *uname, *aisname;
  235.     int    *precedes;
  236.     char   *main_binding_unit = (char *)0;
  237.     int    units_lib;
  238.     int    is_interfaced,comp_status;
  239.  
  240.     init_predef();
  241.     ll_head = (struct axq_loaded   *) 0;
  242.     if (ifile == (IFILE *) 0) {
  243.         printf("*** library is empty\n");
  244.         exit(RC_ERRORS);
  245.     }
  246.     units_lib = getnum(ifile, "lib-unit-count");
  247.     unit_count = getnum(ifile, "lib-unit_num");
  248.     getnum(ifile, "lib-empty-slots"); /* ignore */
  249.     getstr(ifile, "lib-tmp-str");     /* ignore */
  250.     unit_names = (char **) erealloct((char *)unit_names,
  251.       (unit_count+1) * sizeof(char **), "unit_names-re");
  252.  
  253.     file_number = (char **) erealloct((char *)file_number,
  254.         sizeof(char **) *(unit_count+1),"file_number-re");
  255. #ifndef INTERFACE
  256.     if (main_unit != (char *)0) {
  257.         /* a main unit was specified */
  258.         main_binding_uni